<?php

namespace App\Controller;
use lyf\Str;
use Think\Controller;
require './vendor/autoload.php';
header("Access-Control-Allow-Origin: *");
class ApiController extends Controller{

    private $userInfo;
    public function __construct()
    {
        $userInfo = decode_token();
        $this->userInfo = empty($userInfo)?"":(object)$userInfo;
    }

    //数据过滤
    protected function filterdata(){
        $check = CheckFactoryController::inletSet();
        $check->before('apiversion,uuid,nonce,sign,handler,method,device');

        unset($check);

    	//根据需要用function的过滤方法过滤;
    	return $_POST;
    }

	/**
	 * @desc  统一入口文件
	 ==============下方参数为必传参数=================
	 * @param $apiversion     接口版本号
	 * @param $safecode       接口安全码
	 * @param $handler        控制器名字
	 * @param $method         方法名字
	 * @param $method         方法名字
	 * @param $param          接口参数  格式为json格式  {"phone":17091922777,"type":0,"user_id":0}
	 * @param $uuid           设备识别号码
	 ==============下方参数为非必传参数=================
	 */
    public function inlet(){
    	header("Access-Control-Allow-Origin: *");
    	$RequestData       =  $this->filterdata();
        if (!isset($RequestData['sign']) || empty($RequestData['sign']) || !unlock_url($RequestData['sign'],C('Unlock_KEY')) ){

            if ($RequestData['device']!='Egor'){
                $return_data = array(
                    'error'            => 100006,
                    'error_msg'        => L('_SIGNATURE_ERROR_'),
                    'list'      	   => '',
                    'obj'              => '',
                    'page_info'        => '',
                    'request'          => $RequestData,
                );
                $ReData['code'] = '404';
                $ReData['msg'] = L('_REQUEST_ERROR_');
                $ReData['data'] = $return_data;
            }

        }else{
            $unlock_data = unlock_url($RequestData['sign'],C('Unlock_KEY'));

            $arr = explode('&',$unlock_data);
            $tempArr = array();
            foreach ($arr as $k=>$v){
                $exp_arr = explode('=',$v);
                $tempArr[$exp_arr[0]] = $exp_arr[1];
            }

            if ($RequestData['method']!==$tempArr['method']) return $this->output(showErrorMsg('Sign Failed: Data validation failure[method]',100006),I('post.'));
            if ($RequestData['handler']!==$tempArr['handler']) return $this->output(showErrorMsg('Sign Failed: Data validation failure[handler]',100006),I('post.'));
            if ($RequestData['apiversion']!==$tempArr['apiversion']) return $this->output(showErrorMsg('Sign Failed: Data validation failure[apiversion]',100006),I('post.'));
            if ($RequestData['uuid']!==$tempArr['uuid']) return $this->output(showErrorMsg('Sign Failed: Data validation failure[uuid]',100006),I('post.'));
            if ($RequestData['nonce']!==$tempArr['nonce']) return $this->output(showErrorMsg('Sign Failed: Data validation failure[nonce]',100006),I('post.'));
            if ($RequestData['device']!==$tempArr['device']) return $this->output(showErrorMsg('Sign Failed: Data validation failure[device]',100006),I('post.'));
        }

		$apiversion = C('apiversion');
		$token      = _get_token();
        if( $apiversion != $RequestData['apiversion']){
    	    $return_data = array(
				'error'            => 100001,
				'error_msg'        => L('_APIVERSION_ERROR_'),
                'list'      	   => array(),
                'obj'              => new \stdClass(),
                'page_info'        => new \stdClass(),
                'request'          => $RequestData,
    		);
            $ReData['code'] = '404';
            $ReData['msg'] = L('_REQUEST_ERROR_');
            $ReData['data'] = $return_data;
        }else{
	        $HandleStartTime   =  time();
	    	$map['controller'] =  $RequestData['handler'];
	        $map['function']   =  $RequestData['method'];
	        $api_info          =  M('api')->where($map)->find();

	        //test

            if(empty($api_info)){
                $insert_data_api = array(
                    'api_name'  =>  $RequestData['handler'],
                    'controller'  =>  $RequestData['handler'],
                    'function'  =>  $RequestData['method'],
                    'param'  =>  empty($RequestData['param'])?'':$RequestData['param'],
                    'return'  =>  '',
                );
                $api_info = M('api')->add($insert_data_api);
            }
	        if(empty($api_info)){
	        	$return_data = array(
						'error'            => 100002,
						'error_msg'        => L('_INTERFACE_ERROR_'),
		                'list'      	   => array(),
		                'obj'              => new \stdClass(),
		                'page_info'        => new \stdClass(),
		                'request'          => $RequestData,
	        		);
	            $ReData['code'] ='404';//状态码
	            $ReData['msg'] =L('_REQUEST_ERROR_');//提示信息
	            $ReData['data'] = $return_data;
	        }else{
                $where['nonce'] = $RequestData['nonce'];
                $where['handler'] = $RequestData['handler'];
                $where['method'] = $RequestData['method'];
	            $api_log_info = M('api_log')->where($where)->find();
                if (false){
                    $return_data = array(
                        'error'            => 100007,
                        'error_msg'        => L('_DATA_REPLAY_'),
                        'list'      	   => array(),
                        'obj'              => new \stdClass(),
                        'page_info'        => new \stdClass(),
                        'request'          => $RequestData,
                    );
                    $ReData['code'] ='404';//状态码
                    $ReData['msg'] =L('_REQUEST_ERROR_');//提示信息
                    $ReData['data'] = $return_data;
                }else{
                    $ApiLogData = array(
                        'handle_start_time'=> $HandleStartTime,
                        'handler'      	   => $RequestData['handler'],
                        'method'           => $RequestData['method'],
                        'apiversion'       => $RequestData['apiversion'],
                        'handle_stop_time' => 0,
                        'handle_time'      => 0,
                        'request_data'     => json_encode($RequestData),
                        'return_data'      => '',
                        'client_ip'        => client_ip(),
                        'user_token'       => isset($token) ? $token : 0,
                        'user_uuid'        => isset($RequestData['uuid']) ? $RequestData['uuid'] : 0,
                        'user_id'          => empty($this->userInfo)?0:$this->userInfo->id,
                        'error'            => 0,
                        'error_msg'        => '',
                        'user_nickname'    => '',
                        'status'           => 1,   //1开始执行
                        'nonce'            => $RequestData['nonce'],
                        'sign'             => $RequestData['sign'],
                        'device'           => $RequestData['device'],

                    );
                    $ApiLogId = M('api_log') -> add($ApiLogData);
                }
	        }
        }

        if($ReData){
        	$this->export($RequestData['handler'],$RequestData['method'],$RequestData,$ApiLogId,$ReData,0);
        }else{
        	$this->export($RequestData['handler'],$RequestData['method'],$RequestData,$ApiLogId);
        }
    }

    /**
     * @desc        ADC
     * @param      $handler
     * @param      $method
     * @param      $RequestData
     * @param      $ApiLogId
     * @param null $ReData
     * @param int  $status
     */
    protected function export($handler,$method,$RequestData,$ApiLogId,$ReData=null,$status=1){
    	header("Access-Control-Allow-Origin: *");
    	$param   =   json_decode($RequestData['param'],true);
    	if($status == 0){
    		$this->ajaxReturn($ReData);
    	}elseif($status == 1){
    		$ApiLogData       =  M('api_log') -> find($ApiLogId);
	    	$handler          =  A($handler);
	        $ReturnData       =  $handler->$method($param);
	        $HandleStopTime   =  time();
	        $HandleTime       =  $ApiLogData['handle_start_time'] - $HandleStopTime;

    	}
    	$ApiLogData = array(
	    			'id'               => $ApiLogId,
	                'handle_stop_time' => $HandleStopTime,
	                'handle_time'      => $HandleTime,
	                'error'            => empty($ReturnData['error'])?0:$ReturnData['error'],
		            'error_msg'        => $ReturnData['error_msg'],
	                'return_data'      => json_encode($ReturnData),
	                'user_id'          => isset($ReturnData['user_id']) ? (int)$ReturnData['user_id'] : 0,
	                'user_nickname'    => isset($ReturnData['user_nickname']) ? $ReturnData['user_nickname'] : '未登陆',
	                'status'           => $ReturnData['status'],   //1开始执行
	    		);   
	    M('api_log') -> save($ApiLogData);
        if($ReturnData['status'] != 2){
            if ($ReturnData['return_type']==0){
                $return_data = array(
                    'error'            => $ReturnData['error'],
                    'error_msg'        => $ReturnData['error_msg'],
                    'return_type'      => 2,
                    'list'      	   => array(),
                    'page_info'        => new \stdClass(),
                    'obj'              => new \stdClass(),
                    'request'          => $RequestData,
                );
            }elseif ($ReturnData['return_type']==1){
                $return_data = array(
                    'error'            => $ReturnData['error'],
                    'error_msg'        => $ReturnData['error_msg'],
                    'return_type'      => 1,
                    'list'      	   => $ReturnData['return_data'],
                    'page_info'        => empty($ReturnData['page_info'])?new \stdClass():$ReturnData['page_info'],
                    'obj'              => new \stdClass(),
                    'request'          => $RequestData,
                );
            }elseif ($ReturnData['return_type']==2){
                $return_data = array(
                    'error'            => $ReturnData['error'],
                    'error_msg'        => $ReturnData['error_msg'],
                    'return_type'      => 2,
                    'list'      	   => array(),
                    'page_info'        => new \stdClass(),
                    'obj'              => $ReturnData['return_data'],
                    'request'          => $RequestData,
                );
            }
            $ReData['code'] ='405';//状态码
            $ReData['msg'] =L('_INTERFACE_EXECUTION_ERROR_');//提示信息
            $ReData['data'] = $return_data;
        }else{
            if ($RequestData['return_type'] == 0){
                $return_data = array(
                    'error'            => 0,
                    'error_msg'        => $ReturnData['error_msg'],
                    'return_type'      => 2,
                    'list'      	   => array(),
                    'page_info'        => new \stdClass(),
                    'obj'              => new \stdClass(),
                    'request'          => $RequestData,
                );
            }

			if($ReturnData['return_type'] == 1){
				$return_data = array(
					'error'            => 0,
					'error_msg'        => $ReturnData['error_msg'],
					'return_type'      => 1,
					'list'      	   => $ReturnData['return_data'],
	                'page_info'        => $ReturnData['page_info'],
	                'obj'              => new \stdClass(),
	                'request'          => $RequestData,
    			);
			}
			if($ReturnData['return_type'] == 2){
				$return_data = array(
					'error'            => 0,
					'error_msg'        => $ReturnData['error_msg'],
					'return_type'      => 2,
					'list'      	   => array(),
        		    'page_info'        => new \stdClass(),
          			'obj'              => $ReturnData['return_data'],
	                'request'          => $RequestData,
    			);
			}
            $ReData['code'] ='200';//状态码
            $ReData['msg'] =L('_OPERATION_SUCCESS_');//提示信息
            $ReData['data'] = $return_data;
        }
        $this->ajaxReturn($ReData);
    }

    /**
     * @desc 只用于在Check控制器中
     * @author Egor<http://gitee.com/seosite>
     * @param      $ReturnData
     * @param null $RequestData
     * @param int  $status
     */
    public function output($ReturnData,$RequestData=null,$status=1){
        header("Access-Control-Allow-Origin: *");
        if($ReturnData['status'] != 2){
            if ($ReturnData['return_type']==0){
                $return_data = array(
                    'error'            => $ReturnData['error'],
                    'error_msg'        => $ReturnData['error_msg'],
                    'return_type'      => 2,
                    'list'      	   => array(),
                    'page_info'        => new \stdClass(),
                    'obj'              => new \stdClass(),
                    'request'          => $RequestData,
                );
            }elseif ($ReturnData['return_type']==1){
                $return_data = array(
                    'error'            => $ReturnData['error'],
                    'error_msg'        => $ReturnData['error_msg'],
                    'return_type'      => 1,
                    'list'      	   => $ReturnData['return_data'],
                    'page_info'        => empty($ReturnData['page_info'])?new \stdClass():$ReturnData['page_info'],
                    'obj'              => new \stdClass(),
                    'request'          => $RequestData,
                );
            }elseif ($ReturnData['return_type']==2){
                $return_data = array(
                    'error'            => $ReturnData['error'],
                    'error_msg'        => $ReturnData['error_msg'],
                    'return_type'      => 2,
                    'list'      	   => array(),
                    'page_info'        => new \stdClass(),
                    'obj'              => $ReturnData['return_data'],
                    'request'          => $RequestData,
                );
            }
            $ReData['code'] ='405';//状态码
            $ReData['msg'] =L('_INTERFACE_EXECUTION_ERROR_');//提示信息
            $ReData['data'] = $return_data;
        }else{
            if ($ReturnData['return_type'] == 0){
                $return_data = array(
                    'error'            => 0,
                    'error_msg'        => $ReturnData['error_msg'],
                    'return_type'      => 2,
                    'list'      	   => array(),
                    'page_info'        => new \stdClass(),
                    'obj'              => new \stdClass(),
                    'request'          => $RequestData,
                );
            }

            if($ReturnData['return_type'] == 1){
                $return_data = array(
                    'error'            => 0,
                    'error_msg'        => $ReturnData['error_msg'],
                    'return_type'      => 1,
                    'list'      	   => $ReturnData['return_data'],
                    'page_info'        => $ReturnData['page_info'],
                    'obj'              => new \stdClass(),
                    'request'          => $RequestData,
                );
            }
            if($ReturnData['return_type'] == 2){
                $return_data = array(
                    'error'            => 0,
                    'error_msg'        => $ReturnData['error_msg'],
                    'return_type'      => 2,
                    'list'      	   => array(),
                    'page_info'        => new \stdClass(),
                    'obj'              => $ReturnData['return_data'],
                    'request'          => $RequestData,
                );
            }
            $ReData['code'] ='200';//状态码
            $ReData['msg'] =L('_OPERATION_SUCCESS_');//提示信息
            $ReData['data'] = $return_data;
        }
        $this->ajaxReturn($ReData);
    }

	//备用空方法
	public function emptyback(){
		$validateres = validate($_POST);
		if($validateres['code']=='200'){

		}else{
			$ReData['code'] = '-300';
			$ReData['msg'] = L('_APIVERSION_ERROR_');
			$ReData['data'] = $_POST;
		}
		$this->ajaxReturn($ReData);
	}

    /**
     * @desc 发送验证码.阿里大鱼
     * @param $param
     * @return array
     */
	public function sendSms($param)
    {

        $check = CheckFactoryController::isParamSet();
        $check->before($param);

        $check = CheckFactoryController::isChildParamSet();
        $check->before('phone,type');

        unset($check);


        $userObj    = M('User');
        $smsObj     = M('Sms');

        $phone = $param['phone'];
        $type = $param['type'];
        $code       = rand(100000,999999);

        if (empty($phone)) return showErrorMsg('手机号不能为空',100002);

        $userInfo   =   $userObj->where(['phone'=>$phone])->find();
        $smsInfo    =   $smsObj->where(['phone'=>$phone,'type'=>$type])->order('create_time desc')->find();

        $start_time = $smsInfo['create_time']+60;
        if ($smsInfo && $start_time>time()){
            return showErrorMsg('60秒内不允许重复发送验证码',100002);
        }

	    switch ($param['type']) {
	    	case '1'://用户注册发送验证码
                if ($userInfo) return showErrorMsg('该手机号已注册',100002);

                sendAliSms($phone,1,$code);

                $insert_data = array(
                    'uid'           =>  0,
                    'phone'         =>  $phone,
                    'create_time'   =>  NOW_TIME,
                    'code'          =>  $code,
                    'type'          =>  1,
                    'status'        =>  1,
                    'content'       =>  '发送成功'
                );

			    $operation = $smsObj -> add($insert_data);

	    		break;
            case '2'://修改密码
                if (!$userInfo) return showErrorMsg('该手机号未注册',100002);

                sendAliSms($phone,2,$code);

                $insert_data = array(
                    'uid'           =>  $userInfo['id'],
                    'phone'         =>  $phone,
                    'create_time'   =>  NOW_TIME,
                    'code'          =>  $code,
                    'type'          =>  2,
                    'status'        =>  1,
                    'content'       =>  '发送成功'
                );

                $operation = $smsObj -> add($insert_data);

                break;

            case '3'://第三方登录绑定手机号

                sendAliSms($phone,3,$code);

                $insert_data = array(
                    'uid'           =>  empty($userInfo['id'])?0:$userInfo['id'],
                    'phone'         =>  $phone,
                    'create_time'   =>  NOW_TIME,
                    'code'          =>  $code,
                    'type'          =>  3,
                    'status'        =>  1,
                    'content'       =>  '发送成功'
                );

                $operation = $smsObj -> add($insert_data);

                break;

            default://其他操作

                sendAliSms($phone,3,$code);

                $insert_data = array(
                    'uid'           =>  empty($userInfo)?'0':$userInfo['id'],
                    'phone'         =>  $phone,
                    'create_time'   =>  NOW_TIME,
                    'code'          =>  $code,
                    'type'          =>  3,
                    'status'        =>  1,
                    'content'       =>  '发送成功'
                );

                $operation = $smsObj -> add($insert_data);

	    		break;
	    }

	    if ($operation) return showErrorMsg(L('_OPERATION_SUCCESS_'));
        return showErrorMsg(L('_OPERATION_FAIL_'),100002);
	}

    /**
     * @desc 发送验证码
     * @author Egor<http://gitee.com/seosite>
     * @param $param
     * @return array
     */
    public function sendMailCode($param)
    {
        $check = CheckFactoryController::isParamSet();
        $check->before($param);

        $check = CheckFactoryController::isChildParamSet();
        $check->before('email,type');

        unset($check);

        $email = $param['email'];
        $type = $param['type'];

        $userObj = M('User');
        $mailObj = M('send_email');

        $rand = rand(100000,999999);


        switch ($type){
            case 1://注册
                $is_exist = $userObj->where(['email'=>$email])->find();
                if ($is_exist)  return showErrorMsg('邮箱已存在',100095);

                $is_send = $mailObj->where(['email'=>$email,'type'=>1])->find();
                if (!empty($is_send)){
                    $ctime = NOW_TIME - $is_send['create_time'];
                    if ($ctime<60) return showErrorMsg('60秒内不可重复发送邮箱',100002);
                }
                $name = '邮箱注册【赫桥财经】';
                $subject = '邮箱注册【赫桥财经】';//题目
                $body = '感谢您注册 【赫桥财经】，为了保证您正常使用，请妥善保管您的验证码【'.$rand.'】。';//内容
                $operation = think_send_mail($email, $name, $subject, $body, $attachment = null);
                break;

            case 2://修改邮箱
                $is_exist = $userObj->where(['email'=>$email])->find();
                if ($is_exist)  return showErrorMsg('邮箱已存在',100095);
                $is_send = $mailObj->where(['email'=>$email,'type'=>2])->find();
                if (!empty($is_send)){
                    $ctime = NOW_TIME - $is_send['create_time'];
                    if ($ctime<60) return showErrorMsg('60秒内不可重复发送邮箱',100002);
                }

                $name = '修改绑定邮箱【赫桥财经】';
                $subject = '修改绑定邮箱【赫桥财经】';//题目
                $body = '您正在绑定新的邮箱，为了保证您正常使用，请妥善保管您的验证码【'.$rand.'】。';//内容
                $operation = think_send_mail($email, $name, $subject, $body, $attachment = null);
                break;
            default:
                return showErrorMsg(L("_OPERATION_FAIL_"),100095);
        }

        if ($operation===true) {
            $insert_data = array(
                'email' =>  $email,
                'type'  =>  $type,
                'code'  =>  $rand,
                'subject'   =>  $subject,
                'body'  =>  $body,
                'create_time'   =>  NOW_TIME
            );
            $mailObj->add($insert_data);
            return showErrorMsg(L('_OPERATION_SUCCESS_'));
        }else{
            return showErrorMsg($operation,100095);
        }
    }

    /**
     * @desc 文件上传，检测文件是否已经存在，如果存在，则直接返回相对路径
     * @author Earl <guo@seosite.cn> .
     * @updateTime
     * @return array
     */
	public function upload($param)
    {
        $check = CheckFactoryController::isParamSet();
        $check->before($param);

        $check = CheckFactoryController::isChildParamSet();
        $check->before('type');

        unset($check);


        return  file_upload($param['type'],$param['width']);
    }
}



?>